home *** CD-ROM | disk | FTP | other *** search
/ InterCD 2001 April / april_2001.iso / intercd / root / ^Palm / Games / eCross / src / Grid.java < prev    next >
Encoding:
Java Source  |  2000-08-01  |  10.0 KB  |  424 lines

  1. /*
  2.  * Grid.java - The game area grid
  3.  * Copyright (C) 2000 Romain Guy
  4.  * guy.romain@bigfoot.com
  5.  * www.jext.org
  6.  *
  7.  * This program is free software; you can redistribute it and/or
  8.  * modify it under the terms of the GNU General Public License
  9.  * as published by the Free Software Foundation; either version 2
  10.  * of the License, or any later version.
  11.  *
  12.  * This program is distributed in the hope that it will be useful,
  13.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.  * GNU General Public License for more details.
  16.  *
  17.  * You should have received a copy of the GNU General Public License
  18.  * along with this program; if not, write to the Free Software
  19.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  20.  */
  21.  
  22. import waba.fx.*;
  23. import waba.util.*;
  24. import waba.sys.*;
  25.  
  26. /**
  27.  * The grid object represents the game area. It draws a grid
  28.  * which amount of cells can be specified. The grid also holds
  29.  * and handle the solutions of the puzzle.
  30.  * @author Romain Guy <guy.romain@bigfoot.com>
  31.  * @version 1.1
  32.  */
  33.  
  34. public class Grid
  35. {
  36.   // defines the width in pixels of a single cell
  37.   public static final int CELL_WIDTH = 5;
  38.  
  39.   // strings containing infos
  40.   private MiniString[] rowsInfos;
  41.   private MiniString[] colsInfos;
  42.  
  43.   // high score of current level
  44.   private byte[] highScore;
  45.   // the level name
  46.   private String levelName;
  47.   // the level
  48.   private byte[] level;
  49.   // the level viewed by the user
  50.   private byte[] userLevel;
  51.   // 'to be drawn' cells amount
  52.   private int cellsToDraw;
  53.   // number of cells found
  54.   private int cellsFound;
  55.   // number of cells to find
  56.   private int hiddenCells;
  57.   // defines the amount of cells in a row/column
  58.   private int cells;
  59.   // controls like fields
  60.   private int width, height, x, y;
  61.   // the drawing area
  62.   private Graphics g;
  63.   // parent
  64.   private eCross parent;
  65.  
  66.   /**
  67.    * Creates a new grid containing 15 rows and 15
  68.    * columns.
  69.    * @param x The x origin
  70.    * @param y The y origin
  71.    * @param parent The parent of the grid
  72.    */
  73.  
  74.   public Grid(int x, int y, eCross parent)
  75.   {
  76.     this(x, y, 15, parent);
  77.   }
  78.  
  79.   /**
  80.    * Creates a new grid.
  81.    * @param x The x origin
  82.    * @param y The y origin
  83.    * @param cells The amount of cells in each row/column
  84.    * @param parent The parent of the grid
  85.    */
  86.  
  87.   public Grid(int x, int y, int cells, eCross parent)
  88.   {
  89.     int wh = cells * CELL_WIDTH + (cells + 1);
  90.     this.x = x;
  91.     this.y = y;
  92.     this.width = wh;
  93.     this.height = wh;
  94.     this.cells = cells;
  95.     this.parent = parent;
  96.     this.g = parent.getBackBuffer();
  97.   }
  98.  
  99.   /**
  100.    * Sets the current level.
  101.    * @param level The level stored in a byte array
  102.    */
  103.  
  104.   public void setLevel(Level level)
  105.   {
  106.     this.level = level.getLevel();
  107.     this.levelName = level.getName();
  108.     this.highScore = level.getHighScore();
  109.     level = null;
  110.  
  111.     reset();
  112.  
  113.     hiddenCells = 0;
  114.     buildStrings();
  115.   }
  116.  
  117.   /**
  118.    * Checks if given time beats current high score.
  119.    */
  120.  
  121.   public boolean isHighScore(byte minutes, byte seconds)
  122.   {
  123.     if (minutes > highScore[0])
  124.       return true;
  125.     else if (minutes == highScore[0])
  126.     {
  127.       if (seconds > highScore[1])
  128.         return true;
  129.     }
  130.  
  131.     return false;
  132.   }
  133.  
  134.   /**
  135.    * Returns current state of the grid.
  136.    */
  137.  
  138.   public byte[] getUserLevel()
  139.   {
  140.     return userLevel;
  141.   }
  142.  
  143.  
  144.   /**
  145.    * Sets current state of the grid.
  146.    */
  147.  
  148.   public void setUserLevel(byte[] userLevel)
  149.   {
  150.     this.userLevel = userLevel;
  151.     for (int i = 0; i < userLevel.length; i++)
  152.     {
  153.       switch (userLevel[i])
  154.       {
  155.         case 1:
  156.           cellsFound++;
  157.         case 2: case 3:
  158.           cellsToDraw++;
  159.       }
  160.     }
  161.   }
  162.  
  163.   /**
  164.    * Resets the level if user failed.
  165.    */
  166.  
  167.   public void reset()
  168.   {
  169.     this.userLevel = new byte[this.level.length];
  170.     cellsToDraw = cellsFound = 0;
  171.   }
  172.  
  173.   /**
  174.    * Handles a tap on the screen. This method determines in
  175.    * which cell the tape was made. If no cell can be found
  176.    * then we return false.
  177.    * @param tool The tool currently in use
  178.    * @param _x The x coordinate of the event
  179.    * @param _y The y coordinate of the event
  180.    */
  181.  
  182.   public boolean handlePenEvent(byte tool, int _x, int _y)
  183.   {
  184.     int col = (_x - x) / (CELL_WIDTH + 1);
  185.     int row = (_y - y) / (CELL_WIDTH + 1);
  186.  
  187.     if (col >= 0 && col < cells &&
  188.         row >= 0 && row < cells)
  189.     {
  190.       int index = row * cells + col;
  191.  
  192.       switch (tool)
  193.       {
  194.         case Tool.FILLING_TOOL:
  195.           if (level[index] == 1)
  196.           {
  197.             if (userLevel[index] != 1)
  198.             {
  199.               userLevel[index] = 1;
  200.               cellsToDraw++;
  201.               cellsFound++;
  202.               drawCell(index);
  203.               parent.draw();
  204.   
  205.               if (cellsFound == hiddenCells)
  206.                 parent.win(level, levelName);
  207.             }
  208.           } else {
  209.             return false;
  210.           }
  211.           break;
  212.  
  213.         case Tool.HELPER_TOOL:
  214.           if (userLevel[index] != 1)
  215.           {
  216.             userLevel[index] = 2;
  217.             cellsToDraw++;
  218.             drawCell(index);
  219.             parent.draw();
  220.           }
  221.           break;
  222.  
  223.         case Tool.ERASER_TOOL:
  224.           switch (userLevel[index])
  225.           {
  226.             case 1:
  227.               cellsFound--;
  228.             case 2:
  229.               cellsToDraw--;
  230.               userLevel[index] = 3;
  231.               drawCell(index);
  232.               parent.draw();
  233.               break;
  234.           }
  235.           break;
  236.       }
  237.     }
  238.  
  239.     return true;
  240.   }
  241.  
  242.   /**
  243.    * Paints the grid.
  244.    */
  245.  
  246.   public void drawGrid()
  247.   {
  248.     g.setColor(0, 0, 0);
  249.     g.drawRect(x, y, width, height);
  250.  
  251.     for (int i = 0; i < cells - 1; i++)
  252.     {
  253.       int _x = (x + 1) + (i + 1) * CELL_WIDTH + i;
  254.       int _y = (y + 1) + (i + 1) * CELL_WIDTH + i;
  255.  
  256.       if ((i + 1) % 5 == 0)
  257.       {
  258.         g.drawDots(_x, y, _x, y + height - 1);
  259.         g.drawDots(x, _y, x + width - 1, _y);
  260.       } else {
  261.         g.drawLine(_x, y, _x, y + height - 1);
  262.         g.drawLine(x, _y, x + width - 1, _y);
  263.       }
  264.  
  265.       rowsInfos[i].drawText(x - rowsInfos[i].getTextWidth(), _y - CELL_WIDTH, g);
  266.       colsInfos[i].drawText(_x - CELL_WIDTH, y - colsInfos[i].getTextHeight(), g);
  267.     }
  268.  
  269.     rowsInfos[cells - 1].drawText(x - rowsInfos[cells - 1].getTextWidth(),
  270.                                   y + height - (CELL_WIDTH + 1), g);
  271.     colsInfos[cells - 1].drawText(x + width - (CELL_WIDTH + 1),
  272.                                   y - colsInfos[cells - 1].getTextHeight(), g);
  273.   }
  274.  
  275.   /**
  276.    * Draws the content of the cells.
  277.    */
  278.  
  279.   public void drawCells()
  280.   {
  281.     if (cellsToDraw == 0)
  282.       return;
  283.  
  284.     int drawnCells = 0;
  285.  
  286.     for (int i = 0; i < userLevel.length; i++)
  287.     {
  288.       if (drawCell(i))
  289.       {
  290.         if (++drawnCells == cellsToDraw)
  291.           break;
  292.       }
  293.     }
  294.   }
  295.  
  296.   // draws a single cell
  297.  
  298.   private boolean drawCell(int cell)
  299.   {
  300.     g.setColor(0, 0, 0);
  301.     int col = cell % cells;
  302.     int row = cell / cells;
  303.  
  304.     switch (userLevel[cell])
  305.     {
  306.       // filled cell
  307.       case 1:
  308.         g.fillRect((x + 1) + col * CELL_WIDTH + col, (y + 1) + row * CELL_WIDTH + row,
  309.                    CELL_WIDTH - 1, CELL_WIDTH - 1);
  310.         return true;
  311.  
  312.       // checked cell
  313.       case 2:
  314.         int _x = (x + 1) + col * CELL_WIDTH + col;
  315.         int _y = (y + 1) + row * CELL_WIDTH + row;
  316.         g.drawLine(_x + 1, _y + 1, _x + CELL_WIDTH - 2, _y + CELL_WIDTH - 2);
  317.         g.drawLine(_x + CELL_WIDTH - 2, _y + 1, _x + 1, _y + CELL_WIDTH - 2);
  318.         return true;
  319.  
  320.       // erased cell
  321.       case 3:
  322.         g.setColor(255, 255, 255);
  323.         g.fillRect((x + 1) + col * CELL_WIDTH + col, (y + 1) + row * CELL_WIDTH + row,
  324.                    CELL_WIDTH, CELL_WIDTH);
  325.         return true;
  326.     }
  327.  
  328.     return false;
  329.   }
  330.  
  331.   // builds the informations displayed on top and left of the grid
  332.  
  333.   private void buildStrings()
  334.   {
  335.     rowsInfos = new MiniString[cells];
  336.     colsInfos = new MiniString[cells];
  337.  
  338.     boolean filled;
  339.     IntVector current;
  340.     byte[] datas;
  341.  
  342.     // get rows informations
  343.     for (int i = 0; i < cells; i++)
  344.     {
  345.       filled = false;
  346.       current = new IntVector(7);
  347.  
  348.       for (int j = 0; j < cells; j++)
  349.       {
  350.         int _content = level[i * cells + j];
  351.         if (_content == 0)
  352.           continue;
  353.         else
  354.           filled = true;
  355.  
  356.         byte length = 0;
  357.         while (_content == 1)
  358.         {
  359.           j++;
  360.           length++;
  361.           if (j == cells)
  362.             break;
  363.           _content = level[i * cells + j];
  364.         }
  365.  
  366.         current.add(length);
  367.         hiddenCells += length;
  368.       }
  369.  
  370.       if (!filled)
  371.       {
  372.         datas = new byte[1];
  373.         datas[0] = 0;
  374.       } else {
  375.         datas = new byte[current.getCount()];
  376.         for (int k = 0; k < datas.length; k++)
  377.           datas[k] = (byte) current.items[k];
  378.       }
  379.       rowsInfos[i] = new MiniString(datas, MiniString.HORIZONTAL);
  380.     }
  381.  
  382.     // get columns informations
  383.     for (int i = 0; i < cells; i++)
  384.     {
  385.       filled = false;
  386.       current = new IntVector(7);
  387.  
  388.       for (int j = 0; j < cells; j++)
  389.       {
  390.         int _content = level[j * cells + i];
  391.         if (_content == 0)
  392.           continue;
  393.         else
  394.           filled = true;
  395.  
  396.         byte length = 0;
  397.         while (_content == 1)
  398.         {
  399.           j++;
  400.           length++;
  401.           if (j == cells)
  402.             break;
  403.           _content = level[j * cells + i];
  404.         }
  405.  
  406.         current.add(length);
  407.       }
  408.  
  409.       if (!filled)
  410.       {
  411.         datas = new byte[1];
  412.         datas[0] = 0;
  413.       } else {
  414.         datas = new byte[current.getCount()];
  415.         for (int k = 0; k < datas.length; k++)
  416.           datas[k] = (byte) current.items[k];
  417.       }
  418.       colsInfos[i] = new MiniString(datas, MiniString.VERTICAL);
  419.     }
  420.   }
  421. }
  422.  
  423. // End of Grid.java
  424.